﻿using Autofac.Extensions.DependencyInjection;
using FlyingEye.DeviceClients;
using FlyingEye.HttpServices;
using FlyingEye.ViewModels;
using FlyingEye.Views;
using FlyingEye.Views.UserControls;
using FlyingEyeClient.ApplicationServices.SignalRHubs;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Http;
using Microsoft.Extensions.Logging;
using Serilog;
using Serilog.Events;
using System.IO;
using System.Net.Http;
using System.Reflection;

namespace FlyingEye
{
    public class FlyingEyeClientModule
    {
        private static void ConfigureLogger()
        {
            Log.Logger = new LoggerConfiguration()
#if DEBUG
            .MinimumLevel.Debug()
#else
            .MinimumLevel.Information()
#endif
            // 将 Microsoft 命名空间下的日志级别设置为 Information，这意味着来自 Microsoft 命名空间的日志将按 Information 级别进行记录。
            .MinimumLevel.Override("Microsoft", LogEventLevel.Information)
            // 将 Microsoft.EntityFrameworkCore 命名空间下的日志级别设置为 Warning，
            // 这意味着来自 Microsoft.EntityFrameworkCore 命名空间的日志将按 Warning 级别进行记录。
            .MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning)
            // 将当前的日志上下文（LogContext）包含在每个日志事件中。
            .Enrich.FromLogContext()
            // 将日志记录到一个名为 "logs.txt" 的文件中。Async 方法表示日志写入是异步执行的，以提高性能。
            .WriteTo.Async(c => c.File(path: "logs/app/log-.txt", // 注意路径和文件名格式
                  rollingInterval: RollingInterval.Day, // 按天滚动
                  rollOnFileSizeLimit: true, // 在文件大小达到限制时也滚动
                  retainedFileCountLimit: 7, // 保留最近7天的日志文件
                  outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}",
                  fileSizeLimitBytes: 10 * 1024 * 1024 // 每个文件最大10MB
                  ))
            // 将日志输出到控制台。
            .WriteTo.Async(c => c.Console())
            .CreateLogger();
        }

        public IHost Build()
        {
            // 配置 Serilog 作为日志记录器
            ConfigureLogger();

            var builder = Host.CreateApplicationBuilder(new HostApplicationBuilderSettings()
            {
                ContentRootPath = AppContext.BaseDirectory,
#if DEBUG
                EnvironmentName = Environments.Development,
#else
                EnvironmentName = Environments.Production,
#endif
            });

            builder.Configuration.SetBasePath(AppContext.BaseDirectory);
#if DEBUG
            builder.Configuration.AddJsonFile(Path.Combine(AppContext.BaseDirectory, "appsettings.Development.json"));
#else
            builder.Configuration.AddJsonFile(Path.Combine(AppContext.BaseDirectory, "appsettings.json"));
#endif
            builder.ConfigureContainer(new AutofacServiceProviderFactory());

            builder.Logging.AddSerilog();

            ConfigureServices(builder.Configuration, builder.Services);

            return builder.Build();
        }

        public void ConfigureServices(IConfiguration configuration, IServiceCollection services)
        {
            var tmp = configuration.GetSection(nameof(ApplicationOptions));

            services.Configure<ApplicationOptions>(configuration.GetSection(nameof(ApplicationOptions)));
            services.Configure<HttpClientServiceOptions>(configuration.GetSection(nameof(HttpClientServiceOptions)));
            services.Configure<SignalRAuthenticationOptions>(configuration.GetSection(nameof(SignalRAuthenticationOptions)));

            // 配置默认的 HttpClient 
            services.ConfigureHttpClientDefaults(configure =>
            {
                // 如果是 WIN7 系统，禁用 HTTPS 验证
                if (WindowsApi.IsWindows7())
                {
                    configure.ConfigurePrimaryHttpMessageHandler(() =>
                    {
                        var handle = new HttpClientHandler();
                        handle.ServerCertificateCustomValidationCallback = (msg, cert, chain, errors) => true;
                        return handle;
                    });
                }
            });

            services.AddHttpClient();

            services.AddAutoMapper(configuration =>
            {
                configuration.CreateMap<DeviceConfigurationResponse, DeviceConfiguration>();
            });

            services.AddTransient<MainWindow>();
            services.AddTransient<MainWindowViewModel>();
            services.AddTransient<AuthenticationWindow>();
            services.AddTransient<AuthenticationWindowViewModel>();

            services.AddSingleton<ApplicationContext>();
            services.AddTransient<FlyingEyeClientApplication>();
            services.AddTransient<IDeviceClient, DeviceClient>();
            services.AddTransient<DeviceManager>();
            services.AddTransient<SignalRClient>();
            services.AddTransient<HttpClientService>();
            services.AddSingleton<HttpTokenManager>();
            services.AddTransient<DesktopNotificationUserControl>();
            services.AddTransient<ComeNotificationService>();
        }
    }
}
